/**
 * 角色服务实现类 - 处理RBAC权限管理中角色操作的核心业务逻辑
 *
 * 开发人员：马勇俐
 * 开发时间：2025-11-16 至 2025-11-20
 * 模块职责：实现角色的创建、查询、更新、删除等核心业务逻辑，支持RBAC权限模型的角色管理
 *
 * 技术要点：
 * - 多租户角色数据隔离和管理
 * - 角色编码唯一性验证机制
 * - 角色信息完整性校验和更新
 * - 内置角色和自定义角色管理
 * - 异常处理和事务管理机制
 *
 * 开发故事：负责角色服务的核心业务逻辑实现，与角色控制器和权限服务深度配合，确保RBAC权限系统的完整性和安全性。
 */
package com.pbl.service.impl;

import com.pbl.common.exception.BizException;
import com.pbl.entity.Enterprise;
import com.pbl.entity.Role;
import com.pbl.repository.EnterpriseRepository;
import com.pbl.repository.RoleRepository;
import com.pbl.service.RoleService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class RoleServiceImpl implements RoleService {

    private final RoleRepository roleRepository;
    private final EnterpriseRepository enterpriseRepository;

    /**
     * 构造角色服务实现
     * @param roleRepository 角色数据访问层
     * @param enterpriseRepository 企业数据访问层
     */
    public RoleServiceImpl(RoleRepository roleRepository, EnterpriseRepository enterpriseRepository) {
        this.roleRepository = roleRepository;
        this.enterpriseRepository = enterpriseRepository;
    }

    @Override
    public Role create(Long enterpriseId, Role r) {
        Enterprise ent = enterpriseRepository.findById(enterpriseId).orElseThrow(() -> new BizException(404, "企业不存在"));
        roleRepository.findByEnterprise_IdAndCode(enterpriseId, r.getCode()).ifPresent(x -> {
            throw new BizException(400, "角色编码已存在");
        });
        r.setId(null);
        r.setEnterprise(ent);
        return roleRepository.save(r);
    }

    @Override
    public Role update(Long id, Role r) {
        Role db = get(id);
        db.setName(r.getName());
        db.setDescription(r.getDescription());
        return roleRepository.save(db);
    }

    @Override
    public Role get(Long id) {
        return roleRepository.findById(id).orElseThrow(() -> new BizException(404, "角色不存在"));
    }

    @Override
    public void delete(Long id) {
        roleRepository.deleteById(id);
    }

    @Override
    public List<Role> listByEnterprise(Long enterpriseId) {
        return roleRepository.findByEnterprise_Id(enterpriseId);
    }
}
